﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing.Design;
using System.ComponentModel;
using ApplicationGenerator.CommonModule;
using System.Windows.Forms.Design;
using System.Windows.Forms;
using ApplicationGenerator.BusinessModule.Interfaces;
using ApplicationGenerator.BusinessModule.Elements;
using System.IO;
using System.Reflection;
using ApplicationGenerator.CommonForms.Forms;

namespace ApplicationGenerator.CommonForms
{
    public class MappingsEditor : UITypeEditor
    {
        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
            return UITypeEditorEditStyle.Modal;
        }

        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
        {
            IWindowsFormsEditorService edService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
            if (edService != null)
            {
                IWebServiceInvocation webServiceObject = context.Instance as IWebServiceInvocation;
                if (webServiceObject == null)
                {
                    return base.EditValue(context, provider, value);
                }

                if (!ValidateParameters(webServiceObject))
                {
                    return base.EditValue(context, provider, value);
                }

                if (webServiceObject.MetaModelName == null)
                {
                    MessageBox.Show("Należy ustawić meta model dla procesu", "Błąd konfiguracji", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return base.EditValue(context, provider, value);
                }

                IMetaModel metaModel = (new FacadeFactory()).CreateMetaModelFacade().MetaModelCollection[webServiceObject.MetaModelName];
                if (metaModel == null)
                {
                    MessageBox.Show("Nie można pobrać modelu", "Błąd konfiguracji", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return base.EditValue(context, provider, value);
                }

                MappingsForm mappingsForm = null;
                try
                {
                    mappingsForm = new MappingsForm(metaModel, WebServiceConfigurationHelper.GetPath(webServiceObject.WebServiceURL), webServiceObject.MethodName);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Błąd konfiguracji", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return base.EditValue(context, provider, value);
                }

                Mappings mappings = null;
                if (value != null)
                {
                    mappings = MappingsConverterHelper.ConvertToMappings(value as byte[]);
                }

                if (mappings != null)
                {
                    mappingsForm.InitializeMappings(mappings);
                }

                if (edService.ShowDialog(mappingsForm) == System.Windows.Forms.DialogResult.OK)
                {
                    value = MappingsConverterHelper.ConvertToString(mappingsForm.GetConfiguredMappings());
                }
            }

            return value;
        }

        private bool ValidateParameters(IWebServiceInvocation webServiceMethodObject)
        {
            if (string.IsNullOrEmpty(webServiceMethodObject.WebServiceURL))
            {
                MessageBox.Show("Należy podać adres URL do web serwisu", "Błąd konfiguracji", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }

            if (string.IsNullOrEmpty(webServiceMethodObject.MethodName))
            {
                MessageBox.Show("Należy skonfigurować metodę, która ma zostać wywołana przez web serwis", "Błąd konfiguracji", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }

            if (!File.Exists(WebServiceConfigurationHelper.GetPath(webServiceMethodObject.WebServiceURL)))
            {
                MessageBox.Show(string.Format("Plik {0} nie istnieje", WebServiceConfigurationHelper.GetPath(webServiceMethodObject.WebServiceURL)), "Błąd konfiguracji", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }

            Assembly assembly = Assembly.LoadFrom(WebServiceConfigurationHelper.GetPath(webServiceMethodObject.WebServiceURL));
            if (assembly == null)
            {
                MessageBox.Show(string.Format("Nie można załadować {0}", WebServiceConfigurationHelper.GetPath(webServiceMethodObject.WebServiceURL)), "Błąd konfiguracji", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }

            bool methodFound = false;
            foreach (var type in assembly.GetTypes())
            {
                MethodInfo methodInfo = type.GetMethod(webServiceMethodObject.MethodName);
                if (methodInfo != null)
                {
                    methodFound = true;
                    break;
                }
            }

            if (!methodFound)
            {
                MessageBox.Show(string.Format("Metoda {0} nie istnieje", webServiceMethodObject.MethodName), "Błąd konfiguracji", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }

            return true;
        }
    }
}
